package com.roads.workflow.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.roads.common.constant.Constants;
import com.roads.common.constant.TaskConstants;
import com.roads.common.core.domain.entity.SysDept;
import com.roads.common.core.domain.entity.SysUser;
import com.roads.common.utils.DateUtils;
import com.roads.common.utils.StringUtils;
import com.roads.system.mapper.SysDeptMapper;
import com.roads.system.mapper.SysUserMapper;
import com.roads.workflow.domain.WorkflowMeterageDefinition;
import com.roads.workflow.domain.WorkflowMeterageNode;
import com.roads.workflow.domain.WorkflowMeterageNodeUser;
import com.roads.workflow.domain.WorkflowTaskDelivery;
import com.roads.workflow.domain.WorkflowTaskNode;
import com.roads.workflow.domain.WorkflowTaskStep;
import com.roads.workflow.mapper.WorkflowMeterageNodeMapper;
import com.roads.workflow.mapper.WorkflowMeterageNodeUserMapper;
import com.roads.workflow.mapper.WorkflowTaskNodeMapper;
import com.roads.workflow.mapper.WorkflowTaskStepMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.roads.workflow.mapper.WorkflowTaskMapper;
import com.roads.workflow.domain.WorkflowTask;
import com.roads.workflow.service.IWorkflowTaskService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 工作流任务Service业务层处理
 * 
 * @author nhp
 * @date 2022-01-09
 */
@Service
public class WorkflowTaskServiceImpl implements IWorkflowTaskService {

    @Autowired
    private WorkflowTaskMapper workflowTaskMapper;

    @Autowired
    private WorkflowTaskNodeMapper workflowTaskNodeMapper;

    @Autowired
    private WorkflowTaskStepMapper workflowTaskStepMapper;

    @Autowired
    private WorkflowMeterageNodeMapper workflowMeterageNodeMapper;

    @Autowired
    private WorkflowMeterageNodeUserMapper workflowMeterageNodeUserMapper;

    /**
     * 根据任务uuid获取任务信息
     *
     * @param taskUuid 任务uuid
     * @return 任务
     */
    @Override
    public WorkflowTask getWorkflowTask(String taskUuid) {
        return workflowTaskMapper.getModelById(taskUuid);
    }

    /**
     * 根据任务uuid获取流程节点，排除当前位置节点
     *
     * @param taskUuid 任务uuid
     * @return 流程节点
     */
    @Override
    public List<WorkflowMeterageNode> selectListWorkflowNodeByTaskUuid(String taskUuid) {
        return workflowMeterageNodeMapper.selectListWorkflowNodeByTaskUuid(taskUuid);
    }

    /**
     * 根据任务uuid，流程节点uuid，获取流程用户
     * 如果流程节点在流程任务里出现过，直接取流程任务节点，没有出现过，从流程节点里获取
     *
     * @param taskUuid 任务uuid
     * @param workflowNodeUuid 流程节点uuid
     * @return 流程节点用户
     */
    @Override
    public List<SysUser> getWorkflowNodeUser(String taskUuid, String workflowNodeUuid) {
        List<SysUser> nodeUsers = new ArrayList<>();
        // 传送节点
        WorkflowTaskNode taskNode = workflowTaskNodeMapper.getWorkflowNodeByWorkflowNodeUuid(taskUuid, workflowNodeUuid);
        // 如果taskNode为空，则为第一次经过次节点
        if (StringUtils.isNull(taskNode)) {
            WorkflowMeterageNodeUser search = new WorkflowMeterageNodeUser();
            search.setWorkflowNodeUuid(workflowNodeUuid);
            List<WorkflowMeterageNodeUser> meterageNodeUsers = workflowMeterageNodeUserMapper.selectModelList(search);
            for (WorkflowMeterageNodeUser meterageNodeUser : meterageNodeUsers) {
                SysUser user = new SysUser();
                user.setUserName(meterageNodeUser.getUser());
                user.setNickName(meterageNodeUser.getName());
                nodeUsers.add(user);
            }
        } else {
            // 当前节点
            WorkflowTaskNode currentNode = workflowTaskNodeMapper.getWorkflowNodeByPosition(taskUuid);
            WorkflowMeterageNode taskMeterageNode = workflowMeterageNodeMapper.getModelById(taskNode.getWorkflowNodeUuid());
            WorkflowMeterageNode currentMeterageNode = workflowMeterageNodeMapper.getModelById(currentNode.getWorkflowNodeUuid());
            // 如果传送节点大于当前节点，传功--则取出所有用户节点
            // 如果传送节点小于当前节点，退回--则取出已经过的节点
            if (taskMeterageNode.getWorkflowNodeOrder() > currentMeterageNode.getWorkflowNodeOrder()) {
                WorkflowMeterageNodeUser search = new WorkflowMeterageNodeUser();
                search.setWorkflowNodeUuid(workflowNodeUuid);
                List<WorkflowMeterageNodeUser> meterageNodeUsers = workflowMeterageNodeUserMapper.selectModelList(search);
                for (WorkflowMeterageNodeUser meterageNodeUser : meterageNodeUsers) {
                    SysUser user = new SysUser();
                    user.setUserName(meterageNodeUser.getUser());
                    user.setNickName(meterageNodeUser.getName());
                    nodeUsers.add(user);
                }
            } else {
                SysUser user = new SysUser();
                user.setUserName(taskNode.getUser());
                user.setNickName(taskNode.getUserName());
                nodeUsers.add(user);
            }
        }
        return nodeUsers;
    }

    /**
     * 创建工作流任务
     *
     * @param taskUuid 任务uuid
     * @param menuType 菜单类型
     * @param workflowType 流程类型
     * @param loginUser 当前登录用户
     * @param workflowNode 流程节点实例
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createTask(String taskUuid, String workflowType, Integer menuType, SysUser loginUser, WorkflowMeterageNode workflowNode) {
        Date nowDate = DateUtils.getNowDate();
        // 创建任务对象
        WorkflowTask task = new WorkflowTask();
        task.setTaskUuid(taskUuid);
        task.setWorkflowUuid(workflowNode.getWorkflowUuid());
        task.setMenuType(menuType);
        task.setStatus(TaskConstants.TASK_STATUS_CONDUCT);
        task.setCreateBy(loginUser.getUserName());
        task.setCreateTime(nowDate);
        workflowTaskMapper.insert(task);
        // 创建任务节点
        WorkflowTaskNode taskNode= new WorkflowTaskNode();
        taskNode.setTaskUuid(taskUuid);
        taskNode.setWorkflowUuid(workflowNode.getWorkflowUuid());
        taskNode.setWorkflowNodeUuid(workflowNode.getWorkflowNodeUuid());
        taskNode.setDept(loginUser.getDeptId());
        taskNode.setDeptName(loginUser.getDept().getDeptName());
        taskNode.setUser(loginUser.getUserName());
        taskNode.setUserName(loginUser.getNickName());
        taskNode.setPosition(TaskConstants.TASK_CURRENT_POSITION_YES);
        taskNode.setCreateTime(nowDate);
        workflowTaskNodeMapper.insert(taskNode);
        // 创建任务步骤
        WorkflowTaskStep taskStep = new WorkflowTaskStep();
        taskStep.setTaskUuid(taskUuid);
        taskStep.setActionType(TaskConstants.TASK_ACTION_TYPE_CREATE);
        taskStep.setDept(loginUser.getDeptId());
        taskStep.setDeptName(loginUser.getDept().getDeptName());
        taskStep.setUser(loginUser.getUserName());
        taskStep.setUserName(loginUser.getNickName());
        taskStep.setCreateTime(nowDate);
        taskStep.setCreateBy(loginUser.getUserName());
        taskStep.setCreateByName(loginUser.getNickName());
        taskStep.setDescription("创建任务");
        workflowTaskStepMapper.insert(taskStep);
    }

    /**
     * 删除工作流任务
     *
     * @param taskUuid 任务uuid
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteTask(String taskUuid) {
        // 删除任务
        workflowTaskMapper.deleteByTaskUuid(taskUuid);
        // 删除任务节点
        workflowTaskNodeMapper.deleteByTaskUuid(taskUuid);
        // 删除任务步骤
        workflowTaskStepMapper.deleteByTaskUuid(taskUuid);
    }

    /**
     * 完成工作流任务
     *
     * @param taskUuid 任务uuid
     * @param loginUser 当前登录用户
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void finishTask(String taskUuid, SysUser loginUser) {
        // 更改任务状态为完成
        WorkflowTask task = workflowTaskMapper.getModelById(taskUuid);
        task.setStatus(Constants.LOCK);
        workflowTaskMapper.update(task);
        // 新增完成步骤
        WorkflowTaskStep taskStep = new WorkflowTaskStep();
        taskStep.setTaskUuid(taskUuid);
        taskStep.setActionType(TaskConstants.TASK_ACTION_TYPE_FINISH);
        taskStep.setDept(loginUser.getDeptId());
        taskStep.setDeptName(loginUser.getDept().getDeptName());
        taskStep.setUser(loginUser.getUserName());
        taskStep.setUserName(loginUser.getNickName());
        taskStep.setCreateTime(DateUtils.getNowDate());
        taskStep.setCreateBy(loginUser.getUserName());
        taskStep.setCreateByName(loginUser.getNickName());
        taskStep.setDescription("完成任务");
        workflowTaskStepMapper.insert(taskStep);
    }

    /**
     * 删除完成工作流任务
     * 解锁操作，需要删除完成步骤，还原任务状态为未完成
     *
     * @param taskUuid 任务uuid
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteFinishTask(String taskUuid) {
        // 更改任务状态为未完成
        WorkflowTask task = workflowTaskMapper.getModelById(taskUuid);
        task.setStatus(Constants.UNLOCK);
        workflowTaskMapper.update(task);
        // 删除完成步骤
        workflowTaskStepMapper.deleteByFinishStep(taskUuid);
    }

    /**
     * 传送工作流任务
     *
     * @param delivery 传送实体
     * @param loginUser 当前登录用户
     * @param deliveryUser 传送至用户
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deliveryTask(WorkflowTaskDelivery delivery, SysUser loginUser, SysUser deliveryUser) {
        Date nowDate = DateUtils.getNowDate();
        // 流程步骤
        WorkflowTaskStep taskStep = new WorkflowTaskStep();
        taskStep.setTaskUuid(delivery.getTaskUuid());
        taskStep.setDept(deliveryUser.getDeptId());
        taskStep.setDeptName(deliveryUser.getDept().getDeptName());
        taskStep.setUser(deliveryUser.getUserName());
        taskStep.setUserName(deliveryUser.getNickName());
        taskStep.setReason(delivery.getReason());
        taskStep.setCreateTime(nowDate);
        taskStep.setCreateBy(loginUser.getUserName());
        taskStep.setCreateByName(loginUser.getNickName());
        // 获取当前流程节点
        WorkflowTaskNode currentNode = workflowTaskNodeMapper.getWorkflowNodeByPosition(delivery.getTaskUuid());
        // 流程传送至节点
        WorkflowTaskNode deliveryNode = workflowTaskNodeMapper.getWorkflowNodeByWorkflowNodeUuid(delivery.getTaskUuid(), delivery.getWorkflowNodeUuid());
        // 如果传送的节点为空，则是一个新的用户接收，类型为上传
        if (StringUtils.isNull(deliveryNode)) {
            WorkflowTask workflowTask = workflowTaskMapper.getModelById(delivery.getTaskUuid());
            // 设置任务步骤动作为上传
            taskStep.setActionType(TaskConstants.TASK_ACTION_TYPE_UPLOAD);
            taskStep.setDescription("上传");
            // 创建一个新的节点
            deliveryNode = new WorkflowTaskNode();
            deliveryNode.setTaskUuid(delivery.getTaskUuid());
            deliveryNode.setWorkflowUuid(workflowTask.getWorkflowUuid());
            deliveryNode.setWorkflowNodeUuid(delivery.getWorkflowNodeUuid());
            deliveryNode.setDept(deliveryUser.getDept().getDeptId());
            deliveryNode.setDeptName(deliveryUser.getDept().getDeptName());
            deliveryNode.setUser(deliveryUser.getUserName());
            deliveryNode.setUserName(deliveryUser.getNickName());
            deliveryNode.setPosition(TaskConstants.TASK_CURRENT_POSITION_YES);
            deliveryNode.setCreateTime(nowDate);
            workflowTaskNodeMapper.insert(deliveryNode);
        } else {
            deliveryNode.setPosition(TaskConstants.TASK_CURRENT_POSITION_YES);
            // 如果传送节点 大于 当前节点，是上传，小于当前节点是回退
            if (deliveryNode.getTaskNodeId() > currentNode.getTaskNodeId()) {
                taskStep.setActionType(TaskConstants.TASK_ACTION_TYPE_UPLOAD);
                taskStep.setDescription("上传");
            } else {
                taskStep.setActionType(TaskConstants.TASK_ACTION_TYPE_RETURN);
                taskStep.setDescription("回退");
            }
            workflowTaskNodeMapper.update(deliveryNode);
        }
        // 当前节点的位置设置成否
        currentNode.setPosition(TaskConstants.TASK_CURRENT_POSITION_NO);
        workflowTaskNodeMapper.update(currentNode);
        workflowTaskStepMapper.insert(taskStep);
    }

    /**
     * 获取用户节点列表
     *
     * @param taskUuid 任务uuid
     * @return 用户列表
     */
    @Override
    public List<WorkflowTaskNode> selectUserOptions(String taskUuid) {
        return workflowTaskNodeMapper.selectUserOptions(taskUuid);
    }

    /**
     * 查询流程步骤
     *
     * @param taskUuid 任务uuid
     * @return 任务步骤
     */
    @Override
    public List<WorkflowTaskStep> getWorkflowStep(String taskUuid) {
        WorkflowTaskStep taskStep = new WorkflowTaskStep();
        taskStep.setTaskUuid(taskUuid);
        List<WorkflowTaskStep> taskSteps = workflowTaskStepMapper.selectModelList(taskStep);
        return taskSteps;
    }
}
